package yt.demo.appcommondb.base;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.yulichang.base.MPJBaseMapper;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import yt.demo.appcommonbean.exception.LogicException;
import yt.demo.appcommonbean.http.DeleteRequest;
import yt.demo.appcommonbean.http.DetailRequest;
import yt.demo.appcommondb.dto.SplitPageDTO;
import yt.demo.appcommondb.tools.ConditionApplier;
import yt.demo.appcommondb.tools.JConditionApplier;
import yt.demo.appcommondb.tools.ListConverter;
import yt.demo.appcommondb.tools.PageConverter;
import yt.demo.appcommondb.vo.ConditionVO;
import yt.demo.appcommondb.vo.PageVO;
import yt.demo.appcommontools.utils.AssertUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import java.util.List;
import java.util.function.Consumer;
import static com.baomidou.mybatisplus.extension.toolkit.Db.saveBatch;


public abstract class BaseService<T, M extends MPJBaseMapper<T>> {

    protected M mapper;
    private final Class<T> entityClass;

    protected abstract List<ConditionVO<T, ?>> whereConditions(T params);

    protected BaseService(M mapper, Class<T> entityClass) {
        this.mapper = mapper;
        this.entityClass = entityClass;
    }

    public PageVO<T> getPageList(SplitPageDTO dto, T params, Consumer<MPJLambdaWrapper<T>> consumer,List<ConditionVO<T, ?>> whereConditions) {
        List<ConditionVO<T, ?>> conditionsToUse = (whereConditions != null) ? whereConditions : whereConditions(params);
        return PageConverter.convertPage(executePageQuery(dto, entityClass, consumer, conditionsToUse), entityClass);
    }

    public List<T> getList(T params, Consumer<MPJLambdaWrapper<T>> consumer,List<ConditionVO<T, ?>> whereConditions) {
        List<ConditionVO<T, ?>> conditionsToUse = (whereConditions != null) ? whereConditions : whereConditions(params);
        return ListConverter.convertList(executeQuery(consumer, conditionsToUse), entityClass);
    }

    public T create(T req) {
        AssertUtils.isLeZero(mapper.insert(req), "创建失败");
        return req;
    }

    public T update(T req) {
        AssertUtils.isLeZero(mapper.updateById(req), "更新用户！");
        return req;
    }

    public boolean batchInsert(List<T> list) {
       return !saveBatch(list);
    }
    
    public List<T> selectBatchIds(List<Long> ids){
        return mapper.selectBatchIds(ids);
    }

    public void deleteWhere(List<ConditionVO<T, ?>> whereConditions) {
        if (whereConditions == null) {
            throw new LogicException("缺少条件");
        }
        LambdaQueryWrapper<T> wrapper = new LambdaQueryWrapper<>();
        for (ConditionVO<T, ?> condition : whereConditions) {
            if (condition.getSubConditions() != null) {
                ConditionApplier.applySubConditions(wrapper, condition.getSubConditions(), condition.getLogicalOperator());
            } else {
                ConditionApplier.applyCondition(wrapper, condition.getColumn(), condition.getOperator(), condition.getValue());
            }
        }
        mapper.delete(wrapper);
    }

    public void delete(DeleteRequest req) {
        if (ObjectUtil.isNotEmpty(req.getId())) {
            deleteById(req.getId());
        } else if (ObjectUtil.isNotEmpty(req.getIds())) {
            deleteByIds(req.getIds());
        }else {
            throw new LogicException("删除失败");
        }
    }

    public T detail(Long id) {
        return mapper.selectById(id);
    }

    public T detail(Integer id) {
        return mapper.selectById(id);
    }

    public void deleteById(Long id) {
        AssertUtils.isLeZero(mapper.deleteById(id), "删除失败");
    }

    public void deleteByIds(List<Long> ids) {
        AssertUtils.isLeZero(mapper.deleteBatchIds(ids), "删除失败");
    }


    // 通用分页查询方法
    /**
     * w->{
     * w.selectCollection(UserRole.class,AdminUser::getUserRoles); //selectCollection
     * w.leftJoin(UserRole.class,UserRole::getUserId,AdminUser::getId);
     * }
     *
     * @param dto
     * @param dtoClass
     * @param consumer
     * @param whereConditions
     * @return
     */
    public PageVO<T> executePageQuery(SplitPageDTO dto, Class<T> dtoClass, Consumer<MPJLambdaWrapper<T>> consumer, List<ConditionVO<T, ?>> whereConditions) {
        MPJLambdaWrapper<T> wrapper = new MPJLambdaWrapper<>();
        // 用户自定义的查询条件
        if (consumer != null) {
            consumer.accept(wrapper);
        }
        // 应用条件
        if (whereConditions != null) {
            for (ConditionVO<T, ?> condition : whereConditions) {
                if (condition.getSubConditions() != null) {
                    // 如果有子条件，递归处理
                    JConditionApplier.applySubConditions(wrapper, condition.getSubConditions(), condition.getLogicalOperator());
                } else {
                    // 没有子条件时，直接处理
                    JConditionApplier.applyCondition(wrapper, condition.getColumn(), condition.getOperator(), condition.getValue());
                }
            }
        }
        int pageSize = dto.getPageSize() < 0 ? 1000 : dto.getPageSize();
        return new PageVO<>(mapper.selectJoinPage(new Page<>(dto.getPage(), pageSize), dtoClass, wrapper));
    }

    public List<T> executeQuery(Consumer<MPJLambdaWrapper<T>> consumer, List<ConditionVO<T, ?>> whereConditions) {
        MPJLambdaWrapper<T> wrapper = new MPJLambdaWrapper<>();
        // 用户自定义的查询条件
        if (consumer != null) {
            consumer.accept(wrapper);
        }
        // 应用条件
        if (whereConditions != null) {
            for (ConditionVO<T, ?> condition : whereConditions) {
                if (condition.getSubConditions() != null) {
                    // 如果有子条件，递归处理
                    JConditionApplier.applySubConditions(wrapper, condition.getSubConditions(), condition.getLogicalOperator());
                } else {
                    // 没有子条件时，直接处理
                    JConditionApplier.applyCondition(wrapper, condition.getColumn(), condition.getOperator(), condition.getValue());
                }
            }
        }
        // 移除分页逻辑，直接查询所有结果
        return mapper.selectList(wrapper);
    }


}
